home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 04 - 1988 / 04.11 Nov 88 / IAC / Editor Stuff / IAC.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-09-18  |  11.8 KB  |  488 lines  |  [TEXT/MPS ]

  1. /***
  2.  *
  3.  * File:        IAC.c
  4.  *
  5.  * Package:        Inter Application Communications
  6.  *
  7.  * Description:    This is the interface package to the driver for the use of
  8.  *                application programs.
  9.  *
  10.  * Author(s):
  11.  *    FEA        6/19/88
  12.  *
  13.  */
  14.  
  15. # include    <types.h>
  16. # include    <files.h>
  17. # include    <memory.h>
  18. # include    <osutils.h>
  19. # include    <serial.h>
  20. # include    <iac.h>
  21. # include    <dialogs.h>
  22.  
  23. # define    MIN_BLK_SIZE    0xC
  24. # define    DEBUG    false
  25. # define     IAC_ERR_ALRT    257
  26.  
  27. static    short    iac_ref_num;
  28.  
  29. /**
  30.  * Routine: iac_open
  31.  *
  32.  *        The IAC driver is opened by this call and the ioRefNum saved so
  33.  *    it doesn't need to be passed with all calls. A null value is returned
  34.  *    if the open is successful; otherwise the operating system error is
  35.  *    returned.
  36.  */
  37.  
  38. short    iac_open()
  39.  
  40. {
  41. SysEnvRec    theWorld;            /* ALMOST complete knowledge about the world */
  42. THz            s_ZoneP, a_ZoneP;    /* so we can check zone adjacency */
  43. OSErr        the_err;
  44.  
  45. short        result = 0;
  46.  
  47.     the_err = SysEnvirons(1, &theWorld);
  48.     if (theWorld.systemVersion < 0x0420)        /* too early! */
  49.     {
  50.         result = EARLY_SYS;        /* "no multifinder" */
  51.     }
  52.     else
  53.     {
  54.         /*    check for multifinder active by checking if system zone is
  55.             adjacent to application zone, which never happens under
  56.             MultiFinder.
  57.         */
  58.         s_ZoneP = SystemZone();
  59.         a_ZoneP = ApplicZone();
  60.         if ( ((long) s_ZoneP->bkLim + MIN_BLK_SIZE) == (long) a_ZoneP )
  61.         {
  62.             result = EARLY_SYS;        /* zones adjacent - no multifinder */
  63.         }
  64.         else    /* now try to actually open the IAC driver */
  65.         {
  66.             SysBeep(1);
  67.             result = OPENDRIVER("\p.IAC", &iac_ref_num);
  68.         }
  69.     }
  70.  
  71.     return(result);
  72. }
  73.  
  74.  
  75. /**
  76.  * Routine: iac_add_dependency
  77.  *
  78.  *        This is used to inform the IAC driver that a new dependency has been
  79.  *    established and should be added to its internal tables. A null value is
  80.  *    returned if the open is successful; otherwise the operating system error
  81.  *    is returned.
  82.  */
  83.  
  84. short    iac_add_dependency(doc_id, slot_id, hat_check, edition)
  85.     long    *doc_id;    /* identifies the source document (permanent) */
  86.     short    *slot_id;    /* identifies the source document (session) */
  87.     short    *hat_check;    /* extent identifier */
  88.     short    *edition;    /* how many times extent has changed (session) */
  89.  
  90. {
  91. IOParam        the_blk;
  92. OSErr        the_err;
  93.  
  94. struct {
  95.     short    func;
  96.     long    doc_id;
  97.     short    slot_id;
  98.     short    hat_check;
  99.     short    edition;
  100. } my_params;
  101.  
  102. # if DEBUG
  103.     return(the_err=noErr);        /* short circuit for testing without MF */
  104. # endif
  105.  
  106.     my_params.func = 1;                    /* set up private parameter block */
  107.     my_params.doc_id = *doc_id;
  108.     my_params.slot_id = *slot_id;
  109.     my_params.hat_check = *hat_check;
  110.  
  111.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  112.     the_blk.ioRefNum = iac_ref_num;
  113.     the_blk.ioBuffer = &my_params;
  114.     the_blk.ioReqCount = sizeof(my_params);
  115.     the_blk.ioPosMode = fsFromStart;
  116.     the_blk.ioPosOffset = 0;
  117.     the_err = PBWrite(&the_blk.qLink, false);    /* add the dependency */
  118.  
  119.     if (the_err == noErr)        /* update output parameters */
  120.     {
  121.         *doc_id = my_params.doc_id;
  122.         *slot_id = my_params.slot_id;
  123.         *hat_check = my_params.hat_check;
  124.         *edition = my_params.edition;
  125.     }
  126.  
  127.     return(the_err);
  128. }
  129.  
  130.  
  131. /**
  132.  * Routine: iac_complete_dependency
  133.  *
  134.  *        This is used to inform the IAC driver of a document that is interested
  135.  *    in a particular dependency. A null value is returned if the open is
  136.  *    successful; otherwise the operating system error is returned.
  137.  */
  138.  
  139. short    iac_complete_dependency(doc_id, slot_id, hat_check)
  140.     long    *doc_id;    /* identifies the source document (permanent) */
  141.     short    *slot_id;    /* identifies the source document (session) */
  142.     short    *hat_check;    /* extent identifier */
  143.  
  144. {
  145. IOParam        the_blk;
  146. OSErr        the_err;
  147.  
  148. struct {
  149.     short    func;
  150.     long    doc_id;
  151.     short    slot_id;
  152.     short    hat_check;
  153. } my_params;
  154.  
  155. # if DEBUG
  156.     return(the_err=noErr);        /* short circuit for testing without MF */
  157. # endif
  158.  
  159.     my_params.func = 2;                    /* set up private parameter block */
  160.     my_params.doc_id = *doc_id;
  161.     my_params.slot_id = *slot_id;
  162.     my_params.hat_check = *hat_check;
  163.  
  164.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  165.     the_blk.ioRefNum = iac_ref_num;
  166.     the_blk.ioBuffer = &my_params;
  167.     the_blk.ioReqCount = sizeof(my_params);
  168.     the_blk.ioPosMode = fsFromStart;
  169.     the_blk.ioPosOffset = 0;
  170.     the_err = PBWrite(&the_blk.qLink, false);    /* complete the dependency */
  171.  
  172.     if (the_err == noErr)        /* update output parameters */
  173.     {
  174.         *doc_id = my_params.doc_id;
  175.         *slot_id = my_params.slot_id;
  176.         *hat_check = my_params.hat_check;
  177.     }
  178.  
  179.     return(the_err);    
  180. }
  181.  
  182.  
  183. /**
  184.  * Routine: iac_remove_dependency
  185.  *
  186.  *        This is used to inform the IAC driver that a document is no longer
  187.  *    interested in a particular dependency. If the document is the original
  188.  *    source all "targets" will be informed that there is no longer any such
  189.  *    extent; if all targets lose interest the source will be informed that it
  190.  *    no longer needs to update the extent.
  191.  */
  192.  
  193. short    iac_remove_dependency(doc_id, slot_id, hat_check)
  194.     long    doc_id;        /* identifies the source document (permanent) */
  195.     short    slot_id;    /* identifies the source document (session) */
  196.     short    hat_check;    /* extent identifier */
  197.  
  198. {
  199. IOParam        the_blk;
  200. OSErr        the_err;
  201.  
  202. struct {
  203.     short    func;
  204.     long    doc_id;
  205.     short    slot_id;
  206.     short    hat_check;
  207. } my_params;
  208.  
  209. # if DEBUG
  210.     return(the_err=noErr);        /* short circuit for testing without MF */
  211. # endif
  212.  
  213.     my_params.func = 3;                    /* set up private parameter block */
  214.     my_params.doc_id = doc_id;
  215.     my_params.slot_id = slot_id;
  216.     my_params.hat_check = hat_check;
  217.  
  218.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  219.     the_blk.ioRefNum = iac_ref_num;
  220.     the_blk.ioBuffer = &my_params;
  221.     the_blk.ioReqCount = sizeof(my_params);
  222.     the_blk.ioPosMode = fsFromStart;
  223.     the_blk.ioPosOffset = 0;
  224.     the_err = PBWrite(&the_blk.qLink, false);    /* remove the dependency */    
  225.  
  226.     return(the_err);    
  227. }
  228.  
  229.  
  230. /**
  231.  * Routine: iac_available_dependency
  232.  *
  233.  *        This sets the indicated extent as the "available extent" to be used
  234.  *    as the source for future defaulted "complete_dependency"  calls.
  235.  */
  236.  
  237. short    iac_available_dependency(doc_id, hat_check)
  238.     long    doc_id;        /* identifies the source document (permanent) */
  239.     short    hat_check;    /* extent identifier */
  240.  
  241. {
  242. IOParam        the_blk;
  243. OSErr        the_err;
  244.  
  245. struct {
  246.     short    func;
  247.     long    doc_id;
  248.     short    hat_check;
  249. } my_params;
  250.  
  251. # if DEBUG
  252.     return(the_err=noErr);        /* short circuit for testing without MF */
  253. # endif
  254.  
  255.     my_params.func = 4;                    /* set up private parameter block */
  256.     my_params.doc_id = doc_id;
  257.     my_params.hat_check = hat_check;
  258.  
  259.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  260.     the_blk.ioRefNum = iac_ref_num;
  261.     the_blk.ioBuffer = &my_params;
  262.     the_blk.ioReqCount = sizeof(my_params);
  263.     the_blk.ioPosMode = fsFromStart;
  264.     the_blk.ioPosOffset = 0;
  265.     the_err = PBWrite(&the_blk.qLink, false);    /* this dependency is now "available" */
  266.  
  267.     return(the_err);    
  268. }
  269.  
  270.  
  271. /**
  272.  * Routine: iac_status
  273.  *
  274.  *        This allows the application program to find out what's going on.
  275.  */
  276.  
  277. short    iac_status(slot_id, vers_id, doc_count, extent_count)
  278.     short    slot_id;        /* identifies the inquiring document (session) */
  279.     short    *vers_id;        /* driver version*100 */
  280.     short    *doc_count;        /* count of active documents */
  281.     short    *extent_count;    /* count of extents relevant to inquiring doc */
  282.  
  283. {
  284. IOParam        the_blk;
  285. OSErr        the_err;
  286.  
  287. struct {
  288.     short    func;
  289.     short    slot_id;
  290.     short    vers_id;
  291.     short    doc_count;
  292.     short    extent_count;
  293. } my_params;
  294.  
  295. # if DEBUG
  296.     return(the_err=noErr);        /* short circuit for testing without MF */
  297. # endif
  298.  
  299.     my_params.func = 5;                    /* set up private parameter block */
  300.     my_params.slot_id = slot_id;
  301.  
  302.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  303.     the_blk.ioRefNum = iac_ref_num;
  304.     the_blk.ioBuffer = &my_params;
  305.     the_blk.ioReqCount = sizeof(my_params);
  306.     the_blk.ioPosMode = fsFromStart;
  307.     the_blk.ioPosOffset = 0;
  308.     the_err = PBRead(&the_blk.qLink, false);    /* read IAC status */
  309.  
  310.     if (the_err == noErr)        /* update output parameters */
  311.     {
  312.         *vers_id = my_params.vers_id;
  313.         *doc_count = my_params.doc_count;
  314.         *extent_count = my_params.extent_count;
  315.     }
  316.  
  317.     return(the_err);
  318. }
  319.  
  320.  
  321. /**
  322.  * Routine: iac_census
  323.  *
  324.  *        This provides identifying info for all registered extents.
  325.  */
  326.  
  327. short    iac_census(extent_count, extent_info)
  328.     short        *extent_count;    /* count of extents registered */
  329.     info_tblP    extent_info;    /* Ptr to table of info for each extent */
  330.  
  331. {
  332. IOParam        the_blk;
  333. OSErr        the_err;
  334. short        i;
  335.  
  336. struct {
  337.     short        func;
  338.     short        extent_count;
  339.     info_rec    extent_info[MAX_EXTS];
  340. } my_params;
  341.  
  342. # if DEBUG
  343.     return(the_err=noErr);        /* short circuit for testing without MF */
  344. # endif
  345.  
  346.     my_params.func = 6;                    /* set up private parameter block */
  347.  
  348.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  349.     the_blk.ioRefNum = iac_ref_num;
  350.     the_blk.ioBuffer = &my_params;
  351.     the_blk.ioReqCount = sizeof(my_params);
  352.     the_blk.ioPosMode = fsFromStart;
  353.     the_blk.ioPosOffset = 0;
  354.     the_err = PBRead(&the_blk.qLink, false);    /* read IAC status */
  355.  
  356.     if (the_err == noErr)    /* update output parameters */
  357.     {
  358.         *extent_count = my_params.extent_count;
  359.         BlockMove (&my_params.extent_info[0],
  360.                    (Ptr) extent_info,
  361.                    (long) my_params.extent_count * sizeof(info_rec));
  362.     }
  363.  
  364.     return(the_err);
  365. }
  366.  
  367.  
  368. /**
  369.  * Routine: iac_write_data
  370.  *
  371.  *        This updates the data for the specified extent, resulting in a new
  372.  *    change level.
  373.  */
  374.  
  375. short    iac_write_data(doc_id, hat_check, edition, fmt_count, ext_data)
  376.     long    doc_id;        /* identifies the source document (permanent) */
  377.     short    hat_check;    /* extent identifier */
  378.     short    *edition;    /* how many times extent has changed (session) */
  379.     short    fmt_count;    /* number of formats being written */
  380.     Handle    ext_data;    /* Handle to actual data */
  381.  
  382. {
  383. IOParam        the_blk;
  384. OSErr        the_err;
  385.  
  386. struct {
  387.     short    func;
  388.     long    doc_id;
  389.     short    hat_check;
  390.     short    edition;
  391.     short    fmt_count;
  392.     Handle    the_dataH;
  393. } my_params;
  394.  
  395. # if DEBUG
  396.     return(the_err=noErr);        /* short circuit for testing without MF */
  397. # endif
  398.  
  399.     my_params.func = 7;                    /* set up private parameter block */
  400.     my_params.doc_id = doc_id;
  401.     my_params.hat_check = hat_check;
  402.     my_params.fmt_count = fmt_count;
  403.     my_params.the_dataH = ext_data;
  404.  
  405.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  406.     the_blk.ioRefNum = iac_ref_num;
  407.     the_blk.ioBuffer = &my_params;
  408.     the_blk.ioReqCount = sizeof(my_params);
  409.     the_blk.ioPosMode = fsFromStart;
  410.     the_blk.ioPosOffset = 0;
  411.     the_err = PBWrite(&the_blk.qLink, false);    /* update dependency */
  412.  
  413.     if (the_err == noErr)        /* update output parameters */
  414.     {
  415.         *edition = my_params.edition;
  416.     }
  417.  
  418.     return(the_err);
  419. }
  420.  
  421.  
  422. /**
  423.  * Routine: iac_read_data
  424.  *
  425.  *        This is used to retrieve the actual data for the latest change_level
  426.  *    for the specified extent. The IAC driver will record that the inquiring
  427.  *    document has read the data.
  428.  *
  429.  *    ext_data will be resized by the driver to hold the data.
  430.  */
  431.  
  432. short    iac_read_data(doc_id, slot_id, hat_check, edition, fmt_pref,
  433.                   fmt_code, ext_data)
  434.     long    doc_id;            /* identifies the source document (permanent) */
  435.     short    slot_id;        /* identifies the source document (session) */
  436.     short    hat_check;        /* extent identifier */
  437.     short    *edition;        /* how many times extent has changed (session) */
  438.     long    fmt_pref[3];    /* preferred formats, descending desirability */
  439.     long    *fmt_code;        /* format returned to caller */
  440.     Handle    ext_data;        /* Handle to actual data */
  441.  
  442. {
  443. IOParam        the_blk;
  444. OSErr        the_err;
  445.  
  446. struct {
  447.     short    func;
  448.     long    doc_id;
  449.     short    slot_id;
  450.     short    hat_check;
  451.     short    edition;
  452.     long    fmt_pref[3];
  453.     long    fmt_code;
  454.     Handle    ext_data;
  455. } my_params;
  456.  
  457. # if DEBUG
  458.     return(the_err=noErr);        /* short circuit for testing without MF */
  459. # endif
  460.  
  461.     my_params.func = 8;                    /* set up private parameter block */
  462.     my_params.doc_id = doc_id;
  463.     my_params.slot_id = slot_id;
  464.     my_params.hat_check = hat_check;
  465.     my_params.edition = *edition;
  466.     my_params.fmt_pref[0] = fmt_pref[0];
  467.     my_params.fmt_pref[1] = fmt_pref[1];
  468.     my_params.fmt_pref[2] = fmt_pref[2];
  469.     my_params.ext_data = ext_data;
  470.  
  471.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  472.     the_blk.ioRefNum = iac_ref_num;
  473.     the_blk.ioBuffer = &my_params;
  474.     the_blk.ioReqCount = sizeof(my_params);
  475.     the_blk.ioPosMode = fsFromStart;
  476.     the_blk.ioPosOffset = 0;
  477.     the_err = PBRead(&the_blk.qLink, false);    /* read the data */
  478.  
  479.     if (the_err == noErr)
  480.     {
  481.         *edition = my_params.edition;
  482.         *fmt_code = my_params.fmt_code;
  483.     }
  484.  
  485.     return(the_err);
  486. }
  487.  
  488.